x86/np2m: send flush IPIs only when a vcpu is actively using an np2m
authorSergey Dyasli <sergey.dyasli@citrix.com>
Tue, 3 Oct 2017 15:21:01 +0000 (16:21 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 6 Oct 2017 12:36:43 +0000 (13:36 +0100)
commita65a24209cd81fa619097b09d7ede275f8a78bd2
tree631815855a95f94bb694faa5f550409810cb9365
parent7b6546e8314799053ce17241a493742912ad8809
x86/np2m: send flush IPIs only when a vcpu is actively using an np2m

Flush IPIs are sent to all cpus in an np2m's dirty_cpumask when
updated.  This mask however is far too broad.  A pcpu's bit is set in
the cpumask when a vcpu runs on that pcpu, but is only cleared when a
flush happens.  This means that the IPI includes the current pcpu of
vcpus that are not currently running, and also includes any pcpu that
has ever had a vcpu use this p2m since the last flush (which in turn
will cause spurious invalidations if a different vcpu is using an np2m).

Avoid these IPIs by keeping closer track of where an np2m is being used,
and when a vcpu needs to be flushed:

- On schedule-out, clear v->processor in p2m->dirty_cpumask
- Add a 'generation' counter to the p2m and nestedvcpu structs to
  detect changes that would require re-loads on re-entry
- On schedule-in or p2m change:
  - Set v->processor in p2m->dirty_cpumask
  - flush the vcpu's nested p2m pointer (and update nv->generation) if
    the generation changed

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
xen/arch/x86/domain.c
xen/arch/x86/hvm/nestedhvm.c
xen/arch/x86/hvm/vmx/vvmx.c
xen/arch/x86/mm/p2m.c
xen/include/asm-x86/hvm/vcpu.h
xen/include/asm-x86/p2m.h